#ifndef NR_IO_MONGODB_H
#define NR_IO_MONGODB_H

#include "nr_io.h"
#include "mongo/client/dbclient.h"

using namespace mongo;

class nr_io_mongodb : public nr_io
{
public:
    nr_io_mongodb(void);
    
    ~nr_io_mongodb(void);
    
    virtual nr_error_t connect();

    virtual nr_error_t write_data(nr_data* data);
    
    virtual nr_error_t write_event(nr_event* evt);

    virtual nr_error_t query_data(const nr_device_id_t& device_id, QDateTime &begin_time, 
        QDateTime &end_time, QList<nr_data*>& data_list);

    virtual nr_error_t query_event(const nr_device_id_t& device_id, QDateTime &begin_time, 
        QDateTime &end_time, QList<nr_event*>& data_list);

    virtual nr_error_t read_device_types(nr_device_types& device_types);
    virtual nr_error_t write_device_types(nr_device_types& device_types);
    virtual nr_error_t read_device_items(nr_device_item_server& item_server);
    virtual nr_error_t write_device_items(nr_device_item_server& item_server);

    virtual nr_error_t read_roles() { return NR_ERROR_NOT_IMPLEMENTED; }
    
protected:
    nr_device_type* get_device_type(const nr_id_t &type_id);
    bool parse_elementdata( BSONElement& elem, QVariant& variant );
    bool append_BSONObj(BSONObjBuilder& obj_builder, const QString& key, BSONObj& obj);
    bool append_variant(BSONObjBuilder& obj_builder, const QString& key, const QVariant& val);
    bool element_to_data(BSONElement& elem, nr_data& data);

    //read and write device types
    bool read_document_Item( BSONElement& element, nr_device_type_property& devicetypeproperty );
    bool read_document_DeviceType( BSONObj& obj, nr_device_type& devicetype );
    BSONObjBuilder& write_document_Item(nr_device_type_property* property);
    BSONObjBuilder& write_document_SubDeviceType(nr_id_t SubDevice_id);
    BSONObjBuilder& write_document_DeviceType(nr_device_type* devicetype);

    //read and write device items
    bool read_document_Property( BSONObj& obj, nr_device_property& device_property );
    bool read_document_DeviceItem( BSONObj& obj, nr_device_item& device_item );
    bool read_document_DeviceGroup( BSONObj& obj, nr_device_group& device_group, nr_device_item &parent_device_item );
    bool read_document_DeviceItemServer( BSONObj& obj, nr_device_item_server& device_item_server );
    BSONObjBuilder& write_document_Property( nr_device_property* deviceproperty );
    BSONObjBuilder& write_document_DeviceItem( nr_device_item* deviceitem );
    BSONObjBuilder& write_document_DeviceGroup( nr_device_group* devicegroup );
    BSONObjBuilder& write_document_DeviceItemServer( nr_device_item_server* item_server );

private:
    DBClientConnection m_db_client;
    bool m_is_connected;
    nr_device_types *m_device_types;
};

#endif